#include <iostream>
#include <cstdio>

#define P_ADD	0x80
#define P_AND	0x81
#define P_CLR	0x82
#define P_TRAP	0x83
#define P_DIV	0x84
#define P_XOR	0x85
#define P_MOVE	0x86
#define P_MUL	0x87
#define P_OR	0x88
#define P_SUB	0x89
#define P_BRA	0x8a
#define P_BSR	0x8b
#define P_NEG	0x8c
#define P_NOP	0x20
#define P_NOT	0x8d
#define P_TSTB	0x8e
#define P_ILL	0x00
#define P_RTS	0x8f
#define P_IMM	0x90
#define P_IMQ	0x91
#define P_BRK	0xff
#define P_CMPEQ	0x98
#define P_CMPNE	0x99
#define P_CMPLT	0x9a
#define P_CMPGT	0x9b
#define P_CMPLE	0x9c
#define P_CMPGE	0x9d

using namespace std;

unsigned char pcode[] = {
  P_CLR, 0x04,
  P_IMQ, 0x14, 0x03,
  P_IMQ, 0x01, 0x02,
  P_CLR, 0x01,
  P_ADD, 0x02, 0x01,
  P_MOVE, 0x01, 0x00,
  P_MUL, 0x00, 0x00,
  P_ADD, 0x00, 0x04,
  P_CMPLT, 0x01, 0x03, -16,
  P_MOVE, 0x04, 0x01,
  P_CLR, 0x00,
  P_TRAP,
  P_BRK
};

int main() {
  unsigned int pc = 0;
  long d[256];
  long x, y, z, zz;

  for(unsigned short i = 0; i < sizeof(d) / sizeof(long); ++i) d[i] = 0xFFFFFFFF;
  while(pc < sizeof(pcode) && pcode[pc] != 0xff) {
    printf("pc = $%04X $%02x\n", pc, pcode[pc]);
    switch(pcode[pc++]) {
    case P_ADD:
      x = pcode[pc++];
      y = pcode[pc++];
      d[y] += d[x];
      break;
    case P_CLR:
      d[pcode[pc++]] = 0;
      break;
    case P_CMPEQ:
    case P_CMPNE:
    case P_CMPLT:
    case P_CMPGT:
    case P_CMPLE:
    case P_CMPGE:
      z = pcode[pc - 1] & 0x07; //EQ NE LT GT LE GE
      x = d[pcode[pc++]];
      y = d[pcode[pc++]];
      zz = static_cast<signed char>(pcode[pc++]);
      switch(z) {
      case 0x00:
	if(x == y) pc += zz;
	break;
      case 0x01:
	if(x != y) pc += zz;
	break;
      case 0x02:
	if(x < y) pc += zz;
	break;
      case 0x03:
	if(x > y) pc += zz;
	break;
      case 0x04:
	if(x <= y) pc += zz;
	break;
      case 0x05:
	if(x >= y) pc += zz;
	break;
      default:
	cerr << "Illegal CC!\n";
	return 2;
      }
      break;
    case P_MOVE:
      x = pcode[pc++];
      y = pcode[pc++];
      d[y] = d[x];
      break;
    case P_MUL:
      x = d[pcode[pc++]];
      y = pcode[pc++];
      d[y] *= x;
      break;
    case P_IMQ:
      x = pcode[pc++];
      d[pcode[pc++]] = x;
      break;
    case P_TRAP:
      switch(d[0]) {
      case 0:
	printf("$%08lX\n", d[1]);
	break;
      default:
	cerr << "Illegal TRAP!\n";
	return 3;
      }
      break;
    case P_ILL:
    default:
      cerr << "ILLEGAL!\n";
      return 1;
    }
    for(int i = 0; i < 8; ++i) printf(" %08lX", d[i]);
    cout << '\n';
  }
  return 0;
}
